/**
  ************************************* Copyright ******************************
  * FileName   : main.c
  * Version    : v1.0
  * Author     : yychao
  * Date       : 2023-06-28
  * Description:
  * Function List:
  	1. ....
  	   <version>:
  <modify staff>:
  		  <data>:
   <description>:
  	2. ...
  ******************************************************************************
 */
/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * All rights reserved.
 * ****************************************************************************
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ****************************************************************************/

/**
 * @file main.c
 * @author Nations
 * @version v1.0.0
 *
 * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
 */
#include "main.h"
#include "rcc.h"
#include "systick.h"
#include "gpio.h"
#include "tim.h"
#include "usart.h"
#include "log.h"
#include "oled.h"
#include "ds18b20.h"
#include "soft_timer.h"
#include "cpuusage.h"
#include "spi.h"
#include "spi_flash.h"
#include "adc.h"
#include "adc_app.h"
#include "debug.h"
#include "dma.h"
#include "lfs_port.h"
#include "iic.h"
#include "rtc.h"
#include "ble.h"
#include "screen.h"
#include "modbus_slave.h"
#include "modbus_host.h"
#include "io_ctrl.h"
#include "my_protocol.h"
#include "at24cxx.h"
ALIGN(RT_ALIGN_SIZE)

rt_uint8_t msg_pool0[2048];
struct rt_messagequeue static_mq0;
rt_uint8_t msg_pool1[512];
struct rt_messagequeue static_mq1;
rt_uint8_t msg_pool2[512];
struct rt_messagequeue static_mq2;
rt_uint8_t msg_pool3[512];
struct rt_messagequeue static_mq3;

struct rt_mutex static_mutex0;

struct rt_semaphore static_sem0;
struct rt_semaphore static_sem1;
struct rt_semaphore static_sem2;

rt_uint8_t rt0_stack[4096];
struct rt_thread rt0_thread;

rt_uint8_t rt1_stack[4096];
struct rt_thread rt1_thread;

rt_uint8_t rt2_stack[4096];
struct rt_thread rt2_thread;

rt_uint8_t rt3_stack[4096];
struct rt_thread rt3_thread;

rt_uint8_t rt4_stack[4096];
struct rt_thread rt4_thread;

rt_uint8_t rt5_stack[4096];
struct rt_thread rt5_thread;

rt_uint8_t rt6_stack[4096];
struct rt_thread rt6_thread;

static void rt0_thread_entry(void* parameter);
static void rt1_thread_entry(void* parameter);
static void rt2_thread_entry(void* parameter);
static void rt3_thread_entry(void* parameter);
static void rt4_thread_entry(void* parameter);
static void rt5_thread_entry(void* parameter);
static void rt6_thread_entry(void* parameter);
/* -------------------------------- begin  -------------------------------- */
/**
  * @Name    main
  * @brief
  * @param   None
  * @retval
  * @author  {}
  * @Data    2023-02-24
 **/
/* -------------------------------- end -------------------------------- */
int main(void)
{
    rt_thread_delay(10);
    LOG_FUNC();
    /* RTC configer*/
//    rtc_init();
    /* Initialize times*/
    /*PWM Output GPIO*/
    gpio_init_out(GPIOA, GPIO_PIN_11);
    gpio_on(GPIOA, GPIO_PIN_11);
    gpio_init_out(GPIOB, GPIO_PIN_14);
    gpio_on(GPIOB, GPIO_PIN_14);
    /*PWM Enadle GPIO*/
    gpio_init_out(GPIOA, GPIO_PIN_10);
    gpio_on(GPIOA, GPIO_PIN_10);
    gpio_init_out(GPIOB, GPIO_PIN_13);
    gpio_on(GPIOB, GPIO_PIN_13);
    times_init();
    /* Initialize usarts*/
    /* Used for 485 Backup*/
    usart2_init();
//    usart_485initial(BACKUP_485);
//    /* Used for DTU*/
    usart3_init();
    usart_485initial(CNN_485);
    uint8_t test[]= "this is cnn_485 test";
    usart_485trans(CNN_485, &test[0], sizeof(test));
//    /* Used for DW Screen*/
//    usart4_init();
//    /* Used for BlueTooeh E104_BT*/
//    usart5_init();
//    /* Used for 232 Backup*/
//    usart6_init();
//    /* Used for Frequency Changer*/
//    usart7_init();
    /* Initialize Led as output pushpull mode */
    gpio_init_out(GPIOA, GPIO_PIN_1);
    gpio_on(GPIOA, GPIO_PIN_1);
//    /* Initialize spis*/
//    spi_init();
//    /* Initialize iic*/
    iic_init();
    LOG_KEY("The Eeprom Format Is AT24Cxx:[Add(DEC) Val(HEX)]\r\n");
    /* Initialize adc*/
//    adc_init();
    /* Initialize dma*/
//    dma_init();
    io_ctrl_init();

    rt_err_t result;


    result = rt_mq_init(&static_mq0,
                        "mq0",
                        &msg_pool0[0],
                        512,
                        sizeof(msg_pool0),
                        RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create mq0 ok\r\n");
    } else {
    }
    result = rt_mq_init(&static_mq1,
                        "mq1",
                        &msg_pool1[0],
                        256,
                        sizeof(msg_pool1),
                        RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create mq1 ok\r\n");
    } else {
    }
    result = rt_mq_init(&static_mq2,
                        "mq2",
                        &msg_pool2[0],
                        256,
                        sizeof(msg_pool2),
                        RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create mq2 ok\r\n");
    } else {
    }
    result = rt_mq_init(&static_mq3,
                        "mq3",
                        &msg_pool3[0],
                        256,
                        sizeof(msg_pool3),
                        RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create mq3 ok\r\n");
    } else {
    }

    result = rt_mutex_init(&static_mutex0, "mute0", 0);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create mute0 ok\r\n");
    } else {
    }

    result = rt_sem_init(&static_sem0, "sem0", 0, RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create static_sem0 ok\r\n");
    } else {
    }

    result = rt_sem_init(&static_sem1, "sem1", 0, RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create static_sem1 ok\r\n");
    } else {
    }

    result = rt_sem_init(&static_sem2, "sem2", 0, RT_IPC_FLAG_FIFO);
    if (result == RT_EOK)
    {
        LOG_DEBUG("create static_sem2 ok\r\n");
    } else {
    }

    result = rt_thread_init(
                 &rt0_thread,
                 "rt0",
                 rt0_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt0_stack[0],
                 sizeof(rt0_stack),
                 1,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt0_thread);
    } else {
    }


    result = rt_thread_init(
                 &rt1_thread,
                 "rt1",
                 rt1_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt1_stack[0],
                 sizeof(rt1_stack),
                 0,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt1_thread);
    } else {
    }

    result = rt_thread_init(
                 &rt2_thread,
                 "rt2",
                 rt2_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt2_stack[0],
                 sizeof(rt2_stack),
                 2,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt2_thread);
    } else {
    }


    result = rt_thread_init(
                 &rt3_thread,
                 "rt3",
                 rt3_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt3_stack[0],
                 sizeof(rt3_stack),
                 2,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt3_thread);
    } else {
    }

    result = rt_thread_init(
                 &rt4_thread,
                 "rt4",
                 rt4_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt4_stack[0],
                 sizeof(rt4_stack),
                 2,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt4_thread);
    } else {
    }

    result = rt_thread_init(
                 &rt5_thread,
                 "rt5",
                 rt5_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt5_stack[0],
                 sizeof(rt5_stack),
                 2,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt5_thread);
    } else {
    }

    result = rt_thread_init(
                 &rt6_thread,
                 "rt6",
                 rt6_thread_entry,
                 RT_NULL,
                 (rt_uint8_t*)&rt6_stack[0],
                 sizeof(rt6_stack),
                 2,
                 50);
    if (result == RT_EOK)
    {
        rt_thread_startup(&rt6_thread);
    } else {
    }
}

uint8_t major = 0, minor = 0;
uint32_t w25q64_id = 0x00;

static void rt0_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
    static int cnt0 = 0;
    static int cnt1 = 0;
    static int cnt2 = 0;
    static int cnt3 = 0;
    static int tem_cnt = 0;
    static int tem_cnt1 = 0;
    float cache = 0;
    softTimer_Init();
    softTimer_Start(TIMER0, MODE_PERIODIC, 500, TIM0_CB, NULL, 0);

    rt_thread_delay(5);
//	At24cxxWriteOneByte(0,0x55);
//	At24cxxWriteOneByte(1,0xaa);
    At24cxxReadOneByte(0);
    At24cxxReadOneByte(1);



//    uint16_t w25qxx_id = 0x00;
//    w25qxx_id = SPIFLASH_init(0);
//    LOG_DEBUG("W25Qxx ID: %x\r\n", w25qxx_id);
//    lfs_program();
//    oled_init();
//    LCD_ShowStr(0, 0, (uint8_t*)"OLED 128*32 Pixels ", ASC1206, 0);
//    LCD_ShowStr(0, 0 + ASC1206, (uint8_t*)"Just for IIC Test ", ASC1206, 0);
//    LCD_UPDATE();
//    LOG_DEBUG("0.91 OLED Check finished!\r\n");
    while(1) {
        if(cnt0 == 0) {
//            w25q64_id = 0x00;
//            w25q64_id = SPIFLASH_readID(0);
//            major = 0;
//            minor = 0;
//            cpu_usage_get(&major, &minor);


        }
        cnt0++;
        cnt0 %= 1500;
        if(cnt1 == 0) {

        }
        cnt1++;
        cnt1 %= 1000;

        if(cnt2 == 0) {

        }
        cnt2++;
        cnt2 %= 500;
        if(cnt3 == 0) {

        }
        cnt3++;
        cnt3 %= 10;
        softTimer_Update();
        rt_thread_delay(1);
    }
}

/* -------------------------------- begin  -------------------------------- */
/**
  * @Name    rt1_thread_entry
  * @brief
  * @param   parameter: [输入/出]
  * @retval
  * @author  {}
  * @Data    2023-02-24
 **/
/* -------------------------------- end -------------------------------- */

static void rt1_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
    while(1) {
        usart_cache recv_buff;
        memset(&recv_buff, 0x00, sizeof(usart_cache));
        if(0 == rt_mq_recv(&static_mq0, &recv_buff.data[0], sizeof(recv_buff.data), 0)) {
            recv_buff.cnt = recv_buff.data[1];
            recv_buff.cnt = (recv_buff.cnt << 8) | recv_buff.data[2];
//
            if((recv_buff.data[0] != 1)
                    &&(recv_buff.data[0] != 2)
                    &&(recv_buff.data[0] != 3)
                    &&(recv_buff.data[0] != 4))
            {
                LOG_DEBUG("[%01d][%03d]:", recv_buff.data[0], recv_buff.cnt - 3);
                usart_trans(USART1, &recv_buff.data[3], recv_buff.cnt - 3);
                LOG_DEBUG("\r\n");
            }
            switch(recv_buff.data[0]) {
            case 1:
                debug_deal(&recv_buff);
                break;
            case 2:
                screen_deal(&recv_buff);
#if 0
                usart_485trans(BACKUP_485, &recv_buff.data[3], recv_buff.cnt - 3);
#endif
                break;
            case 3:
//                usart_485trans(CNN_485, &recv_buff.data[3], recv_buff.cnt - 3);
                cnn_485_deal(&recv_buff);
//                MODS_Deal(&recv_buff);
                break;
            case 4:
//                MODH_Deal(&recv_buff);
                break;
            case 5:
//                ble_deal(&recv_buff);
                break;
            case 6:
//                usart_trans(UART6, &recv_buff.data[3], recv_buff.cnt - 3);
                break;
            case 7:
//                usart_trans(UART7, &recv_buff.data[3], recv_buff.cnt - 3);
                break;
            }

        }
        rt_thread_delay(1);
    }
}
static void rt2_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
    screen_ini();
    while(1) {
        Screen_OutQueue();
        screen_analyze(&screen_ctrl_st);
        rt_thread_delay(1);
    }
}
static void rt3_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
//    ble_module_initial();
    while(1) {
        rt_thread_delay(1);
    }
}
static void rt4_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
//    MODS_Ini();
    while(1) {
//        MODS_OutQueue();
        rt_thread_delay(1);
    }
}

static void rt5_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    uint16_t cache = 0;
    float temp = 0;
    LOG_FUNC();
    while(1) {
        /*coil*/
        read(REG_COIL,00,10);
        rt_thread_delay(200);
        write(REG_COIL,00,10, (uint16_t*)&pro_data_trans_st.coil[0]);
        rt_thread_delay(200);
        /*dis*/
        /*hold*/
        /*input*/
        read(REG_INPUT,00,4);
        rt_thread_delay(200);
    }
}
static void rt6_thread_entry(void* parameter)
{
    rt_thread_delay(10);
    LOG_FUNC();
    while(1) {
        ctrl_manage();

//		gpio_on(GPIOA, GPIO_PIN_15);
//		gpio_on(GPIOB, GPIO_PIN_5);
//		rt_thread_delay(3000);
//		gpio_off(GPIOA, GPIO_PIN_15);
//		gpio_off(GPIOB, GPIO_PIN_5);
//		rt_thread_delay(100);
//		gpio_on(GPIOA, GPIO_PIN_15);
//		gpio_off(GPIOB, GPIO_PIN_5);
//		rt_thread_delay(3000);
//		gpio_off(GPIOA, GPIO_PIN_15);
//		gpio_off(GPIOB, GPIO_PIN_5);
//		rt_thread_delay(100);

        rt_thread_delay(1);
    }
}
/**
 * @brief Assert failed function by user.
 * @param file The name of the call that failed.
 * @param line The source line number of the call that failed.
 */
#ifdef USE_FULL_ASSERT
void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
    while (1)
    {
    }
}
#endif // USE_FULL_ASSERT

